package psend

import (
	"encoding/gob"
	"fmt"
	"net"
	"os"
	"os/signal"
	"syscall"
)

// 运行定义的服务端
func (s *Server_engine) Server() {
	fmt.Println("已启动服务端,主机中所属地址为：" + s.addr)
	signalCh:=make(chan os.Signal,1)
	signal.Notify(signalCh, syscall.SIGINT, syscall.SIGTERM)
	<-signalCh
}



// 引入一个通讯对象地址，以及要接收的struct的格式
func (c *Client_engine) Init(addr string, struct_type any) error {
	c.conn_pool[addr]=new(Client_conn)
	c.conn_pool[addr].ch=make(chan net.Conn,c.size)
	c.conn_pool[addr].size=c.size
	c.conn_pool[addr].len=0
	gob.Register(struct_type)
	for(c.conn_pool[addr].len<c.size){
		conn, err := net.Dial("tcp", addr)
		if err != nil {
			fmt.Println("连接服务端失败")
			return err
		}
		c.conn_pool[addr].ch <- conn
		c.conn_pool[addr].len++
	}	
	fmt.Println("init执行已连接到服务端，地址为：" + addr)
	return nil
}

// 发送数据给你引入过的已登记通讯对象地址的接口
func (c *Client_engine) Send(path string,date any,out any) (error) {
	conn := <-c.conn_pool[path].ch
	god, err1 := encode_gob(date)
	if err1 != nil {
		return err1
	}
	_, err := conn.Write(god)
	if err != nil {
		conn.Close()
		return err
	}
	rev_date := make([]byte, 1024)
	_, err2 := conn.Read(rev_date)
	if err2 != nil {
		conn.Close()
		return err2
	}

	if err := decode_gob(rev_date,out); err != nil {
		fmt.Println("send读取数据失败")
		return err
	}
	c.conn_pool[path].ch <- conn
	return nil
}

// 监听对方的请求，并处理请求的方法,输入定义的进入接口，要接受的数据类型，以及处理请求的方法
func (s *Server_engine) Listen(path string, struct_type any, handler func(c *C_content)) {
	spath :="@"+s.addr + path
	if _, err := os.Stat(spath); err == nil {
		os.Remove(spath)
	}
	gob.Register(struct_type)

	 go han(handler, spath)
}

// 读取对方发送过来的数据的方法
func (c *C_content) Read(data any) error {
	buffer := make([]byte, 1024)
	if _, err := c.con.Read(buffer); err != nil {
		return err
	}
	if err := decode_gob(buffer, data); err != nil {
		return err
	}
	fmt.Println("收到数据：" + fmt.Sprintf("%v", data))
	return nil
}

// 向对方发送数据的方法
func (c *C_content) Write(data any) error {
	fmt.Println("发送数据：" + fmt.Sprintf("%v", data))
	god, err := encode_gob(data)
	if err != nil {
		return err
	}
	_, err = c.con.Write(god)
	if err != nil {
		return err
	}
	fmt.Println("发送完成")
	return nil
}
